package ;

import hant.Log;
import hant.FlashDevelopProject;
import orm.Db;
import hant.PathTools;
import stdlib.FileSystem;
import haxe.io.Path;
import sys.io.File;
using stdlib.StringTools;


class OrmGenerator
{
	var log : Log;
	var project : FlashDevelopProject;
	var srcPath : String;
	
	public function new(log:Log, project:FlashDevelopProject, srcPath:String)
    {
		this.log = log;
		this.project = project;
		this.srcPath = PathTools.normalize(srcPath != "" ? srcPath : project.srcPath) + "/";
	}
	
	public function generate(db:Db, autogenPackage:String, customPackage:String)
	{
		var autogenOrmClassName = autogenPackage + ".Orm";
		var customOrmClassName = customPackage + ".Orm";
		
		var tables = new Array<OrmTable>();
		
		for (tableName in db.connection.getTables())
        {
			var table = new OrmTable(tableName, autogenPackage, customPackage);
			new OrmModelGenerator(log, project).make(db, table, customOrmClassName, srcPath);
			new OrmManagerGenerator(log, project).make(db, table, customOrmClassName, srcPath);
			tables.push(table);
        }
		
		make(tables, autogenOrmClassName, customOrmClassName);
    }
	
	
	function make(tables:Array<OrmTable>, autogenOrmClassName:String, customOrmClassName:String)
	{
		log.start("MANAGERS => " + customOrmClassName);
		
		var autogenOrm = getAutogenOrm(tables, autogenOrmClassName);
		var destFileName = srcPath + autogenOrmClassName.replace(".", "/") + ".hx";
		FileSystem.createDirectory(Path.directory(destFileName));
		File.saveContent(
			 destFileName
			,"// This is autogenerated file. Do not edit!\n\n" + autogenOrm.toString()
		);
		
		log.finishOk();
	}
	
	function getAutogenOrm(tables:Array<OrmTable>, fullClassName:String) : HaxeClass
	{
		var clas = new HaxeClass(fullClassName);
		
		for (t in tables)
		{
			clas.addVar( { haxeName:t.varName, haxeType:t.customManagerClassName, haxeDefVal:null }, false, false, true);
		}
		
		clas.addMethod(
			  "new"
			, [
				{ haxeName:"db", haxeType:"orm.Db", haxeDefVal:null } 
			  ]
			, "Void"
			, Lambda.map(tables, function(t) return "this." + t.varName + " = new " + t.customManagerClassName + "(db, cast this);").join("\n")
		);
        
		return clas;
	}
	
}
